package coreModel;

import reports.directors.IVisitor;
import hitExceptions.InvalidDataException;
import hitExceptions.InvalidOperationException;

/**
 * This class is almost identical to the StorageUnit; however it has some additional 
 * functionality that needs to be implemented.
 * @author Fantastic four
 * 
 */
@SuppressWarnings("serial")
public class ProductGroup extends ProductContainer
{
	Supply threeMonths;
	ProductContainer parent;


	/**
	 * Constructor
	 * @param parent ProductContainer that this productGroup is in
	 * @param threeMonths a supply object containing the 3 month supply info
	 */
	public ProductGroup(String name, ProductContainer parent,
			Supply threeMonths) throws InvalidDataException
			{
		super(name);
		this.parent=parent;
		this.threeMonths=threeMonths;
			}


	/**
	 * returns the product groups supply object
	 * @return the object representing the 3 months supply
	 */
	public Supply getThreeMonths()
	{
		return threeMonths;
	}

	/**
	 * @param threeMonths the Supply to set as the 3 months quota
	 * @throws InvalidOperationException when the supply is invalid
	 */
	public void setThreeMonths(Supply threeMonths) throws InvalidOperationException
	{
		try
		{
			threeMonths.validateSupplySize();
		}
		catch(InvalidDataException e)
		{
			//changes error message to make it better;
			throw new InvalidOperationException("Three months supply size can't be negative");
		}

		this.threeMonths = threeMonths;
	}

	/**
	 * returns the parent of this group
	 * @return the productContainer parent to the given ProductGroup
	 */
	public ProductContainer getParent()
	{
		return parent;
	}

	/**
	 * This method should be useful when moving different PGroups to one PContainer to another
	 * @param parent used to change the parent Container of the PGroup. 
	 */
	public void setParent(ProductContainer parent)
	{
		this.parent = parent;
	}


	/**
	 * Method for data integrity enforcement
	 * @param supply
	 * @return True iff supply is valid
	 */
	boolean isValidSupply(Supply supply)
	{
		try
		{
			supply.validateSupplySize();
		}
		catch(InvalidDataException e)
		{
			return false;
		}
		return true;
	}

	@Override
	public boolean equals(Object obj)
	{
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		if (this.getName().equals(((ProductGroup)obj).getName()))
			return true;
		else 
			return false;


	}

	@Override
	public void preOrderAccept(IVisitor visitor)
	{
		visitor.visit(this);
		for(ProductGroup pg: this.getChildren())
		{
			pg.preOrderAccept(visitor);
		}
		
		
	}
	
	@Override
	public void postOrderAccept(IVisitor visitor)
	{
		
		for(ProductGroup pg: this.getChildren())
		{
			pg.postOrderAccept(visitor);
		}
		visitor.visit(this);
		
	}
	
	
	


}
